package main

import (
	"fmt"
	"leetcode/datastruct"
)

func main() {
	status := []int{1,0,1,0}
	cadnies := []int{7,5,4,100}
	keys := [][]int{[]int{},[]int{},[]int{1},[]int{}}
	containedBoxes := [][]int{[]int{1,2},[]int{3},[]int{},[]int{}}
	initialBoxes := []int{0}
	res := maxCandies(status,cadnies,keys,containedBoxes,initialBoxes)
	fmt.Println(res)
}


/*
给你 n 个盒子，每个盒子的格式为 [status, candies, keys, containedBoxes] ，其中：
状态字 status[i]：整数，如果 box[i] 是开的，那么是 1 ，否则是 0 。
糖果数 candies[i]: 整数，表示 box[i] 中糖果的数目。
钥匙 keys[i]：数组，表示你打开 box[i] 后，可以得到一些盒子的钥匙，每个元素分别为该钥匙对应盒子的下标。
内含的盒子 containedBoxes[i]：整数，表示放在 box[i] 里的盒子所对应的下标。
给你一个 initialBoxes 数组，表示你现在得到的盒子，你可以获得里面的糖果，也可以用盒子里的钥匙打开新的盒子，还可以继续探索从这个盒子里找到的其他盒子。
请你按照上述规则，返回可以获得糖果的 最大数目 。
来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/maximum-candies-you-can-get-from-boxes
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
*/


func maxCandies(status []int, candies []int, keys [][]int, containedBoxes [][]int, initialBoxes []int) int {
	if len(initialBoxes) == 0 {
		return 0
	}
	total := 0 //总数
	lockList := datastruct.NewQueue() //待开列表
	lockList.Add(initialBoxes)
	keyMap := make(map[int]bool) //打开盒子的钥匙
	boxCountMap := make(map[int]int)
	for lockList.Empty() == false{ //逐个打开初始拥有的盒子，如果状态为1，就打开，如果不为1，放进带开的列表中
		b,index := lockList.Pop()
		if b == true{
			if boxCountMap[index] ==2{
				return total
			}
			_,other :=keyMap[index]
			if status[index] == 1 || other== true{
				delete(keyMap, index)
				total += candies[index]
				if len(keys[index]) != 0{
					for _, n := range keys[index]{
						keyMap[n] = true
					}
				}
				if len(containedBoxes[index]) != 0{
					lockList.Add(containedBoxes[index])
				}
			}else {
				lockList.Add([]int{index})
				boxCountMap[index] = boxCountMap[index]+1
			}
			fmt.Println(lockList)
		}else {
			return total
		}

	}

	return total
}

